home *** CD-ROM | disk | FTP | other *** search
- {*********************************************************}
- {* AACrypt *}
- {* Copyright (c) Julian M Bucknall 1998-2000 *}
- {* All rights reserved. *}
- {*********************************************************}
- {* Algorithms Alfresco simulated annealing unit *}
- {*********************************************************}
-
- {Note: this unit is released as freeware. In other words, you are free
- to use this unit in your own applications, however I retain all
- copyright to the code. JMB}
-
- unit AACrypt;
-
- interface
-
- uses
- SysUtils,
- Classes;
-
- type
- TaaADFGVXTable = string[36];
-
- procedure AACaesarCipher(aEncrypt : boolean;
- N : integer;
- aInStream : TStream;
- aOutStream : TStream);
-
- procedure AAVigenereCipher(aEncrypt : boolean;
- aKey : string;
- aInStream : TStream;
- aOutStream : TStream);
-
- function AAGenADFGVXTable : TaaADFGVXTable;
-
- procedure AAADFGVXCipher(aEncrypt : boolean;
- aKey : string;
- const aSubstTable: TaaADFGVXTable;
- aInStream : TStream;
- aOutStream : TStream);
-
- procedure AAXORCipher(aKey : PByteArray;
- aKeyLen : integer;
- aInStream : TStream;
- aOutStream : TStream);
-
-
- implementation
-
- {====================================================================}
- procedure AACaesarCipher(aEncrypt : boolean;
- N : integer;
- aInStream : TStream;
- aOutStream : TStream);
- var
- BytesRead : longint;
- i : integer;
- Ch : byte;
- Buf : array [0..255] of byte;
- begin
- {force N in range 0..25}
- N := N mod 26;
- if (N < 0) then
- inc(N, 26);
- if not aEncrypt then
- N := 26 - N;
- {read through the input stream in blocks, encrypt the block, and
- write it to the output stream--only convert A-Z and a-z}
- BytesRead := aInStream.Read(Buf, sizeof(Buf));
- while (BytesRead > 0) do begin
- for i := 0 to pred(BytesRead) do begin
- Ch := Buf[i];
- if ((ord('A') <= Ch) and (Ch <= ord('Z'))) then
- Buf[i] := ((Ch - ord('A') + N) mod 26) + ord('A')
- else if ((ord('a') <= Ch) and (Ch <= ord('z'))) then
- Buf[i] := ((Ch - ord('a') + N) mod 26) + ord('a')
- end;
- aOutStream.Write(Buf, BytesRead);
- BytesRead := aInStream.Read(Buf, sizeof(Buf));
- end;
- end;
- {====================================================================}
-
-
- {====================================================================}
- procedure AAVigenereCipher(aEncrypt : boolean;
- aKey : string;
- aInStream : TStream;
- aOutStream : TStream);
- var
- BytesRead : longint;
- i, j : integer;
- Ch : byte;
- Buf : array [0..255] of byte;
- OutBuf : array [0..255] of byte;
- KeyValues : array [0..255] of byte;
- KeyLen : integer;
- KeyInx : integer;
- begin
- {the Vigenere cipher is for uppercase alphabetic letters only; in
- calculating the key values assume the key is in such a state}
- KeyLen := 0;
- for i := 1 to length(aKey) do
- if ('a' <= aKey[i]) and (aKey[i] <= 'z') then begin
- KeyValues[KeyLen] := ord(aKey[i]) - ord('a');
- inc(KeyLen);
- end
- else if ('A' <= aKey[i]) and (aKey[i] <= 'Z') then begin
- KeyValues[KeyLen] := ord(aKey[i]) - ord('A');
- inc(KeyLen);
- end;
- if not aEncrypt then
- for i := 0 to pred(KeyLen) do
- KeyValues[i] := 26 - KeyValues[i];
- {read through the input stream in blocks, encrypt the block, and
- write it to the output stream--only convert and write A-Z and a-z}
- KeyInx := 0;
- BytesRead := aInStream.Read(Buf, sizeof(Buf));
- j := 0;
- while (BytesRead > 0) do begin
- for i := 0 to pred(BytesRead) do begin
- Ch := Buf[i];
- if ((ord('A') <= Ch) and (Ch <= ord('Z'))) then begin
- OutBuf[j] := ((Ch - ord('A') + KeyValues[KeyInx]) mod 26) + ord('A');
- inc(j);
- KeyInx := (KeyInx + 1) mod KeyLen;
- end
- else if ((ord('a') <= Ch) and (Ch <= ord('z'))) then begin
- OutBuf[j] := ((Ch - ord('a') + KeyValues[KeyInx]) mod 26) + ord('A');
- inc(j);
- KeyInx := (KeyInx + 1) mod KeyLen;
- end;
- end;
- aOutStream.Write(OutBuf, j);
- BytesRead := aInStream.Read(Buf, sizeof(Buf));
- j := 0;
- end;
- end;
- {====================================================================}
-
-
- {====================================================================}
- procedure AAADFGVXCipher(aEncrypt : boolean;
- aKey : string;
- const aSubstTable: TaaADFGVXTable;
- aInStream : TStream;
- aOutStream : TStream);
- const
- ADFGVX : array [0..5] of char = 'ADFGVX';
- var
- BytesRead : longint;
- i, j : integer;
- Ch : char;
- Buf : array [0..255] of char;
- DblBuf : array [0..511] of char;
- CleanKey : string;
- KeyLen : integer;
- KeyInx : integer;
- PosCh : integer;
- MinInx : integer;
- ColLen : integer;
- Row, Col : integer;
- SubstTextSize : longint;
- InStreamSize : longint;
- MemStream : TMemoryStream;
- begin
- {clean up the key so that it consists only of unique uppercase
- characters}
- CleanKey := '';
- for i := 1 to length(aKey) do begin
- Ch := upcase(aKey[i]);
- if ('A' <= Ch) and (Ch <= 'Z') then
- if (Pos(Ch, CleanKey) = 0) then
- CleanKey := CleanKey + Ch;
- end;
- {===ENCRYPTION===}
- if aEncrypt then begin
- {read the entire input stream, converting into letterpairs into a
- temporary stream}
- MemStream := TMemoryStream.Create;
- try
- BytesRead := aInStream.Read(Buf, sizeof(Buf));
- while (BytesRead > 0) do begin
- j := 0;
- for i := 0 to pred(BytesRead) do begin
- Ch := upcase(Buf[i]);
- if (('A' <= Ch) and (Ch <= 'Z')) or
- (('0' <= Ch) and (Ch <= '9')) then begin
- PosCh := Pos(Ch, aSubstTable) - 1;
- DblBuf[j] := ADFGVX[PosCh div 6];
- DblBuf[j+1] := ADFGVX[PosCh mod 6];
- inc(j, 2);
- end;
- end;
- MemStream.Write(DblBuf, j);
- BytesRead := aInStream.Read(Buf, sizeof(Buf));
- end;
- {now read the letters in each column according to the order of
- the letters in the cleaned key}
- KeyLen := length(CleanKey);
- for KeyInx := 1 to KeyLen do begin
- {find the smallest letter in the key, this is the column we'll
- be reading next}
- MinInx := 1;
- for i := 2 to KeyLen do
- if (CleanKey[i] < CleanKey[MinInx]) then
- MinInx := i;
- CleanKey[MinInx] := #127; {so we don't see it again}
- dec(MinInx); {it's easier with a 0-based number}
-
- {starting off with the MinInx'th letter in the temporary
- stream, copy it and every KeyLen'th letter after that to the
- output stream}
- SubstTextSize := MemStream.Size;
- PosCh := MinInx;
- j := 0;
- while (PosCh < SubstTextSize) do begin
- MemStream.Position := PosCh;
- inc(PosCh, KeyLen);
- MemStream.Read(DblBuf[j], 1);
- inc(j);
- if (j = sizeof(DblBuf)) then begin
- aOutStream.Write(DblBuf, sizeof(DblBuf));
- j := 0;
- end;
- end;
- if (j > 0) then
- aOutStream.Write(DblBuf, j);
- end;
- finally
- MemStream.Free;
- end;
- end
- {===DECRYPTION===}
- else begin
- {first create the memory stream we'll use as an intermediary, set
- its size to the size of the input stream}
- InStreamSize := aInStream.Size;
- MemStream := TMemoryStream.Create;
- try
- MemStream.SetSize(InStreamSize);
- {now read the letters in each column according to the order of
- the letters in the cleaned key}
- KeyLen := length(CleanKey);
- for KeyInx := 1 to KeyLen do begin
- {find the smallest letter in the key, this is the column we'll
- be reading next}
- MinInx := 1;
- for i := 2 to KeyLen do
- if (CleanKey[i] < CleanKey[MinInx]) then
- MinInx := i;
- CleanKey[MinInx] := #127; {so we don't see it again}
- dec(MinInx); {it's easier with a 0-based number}
-
- {calculate the length of this column}
- ColLen := InStreamSize div KeyLen;
- if ((InStreamSize - (ColLen * KeyLen)) > MinInx) then
- inc(ColLen);
-
- {copy the column from the input stream to the temporary
- stream, starting off by copying to the MinInx'th letter in
- the temporary stream, and every KeyLen'th letter after that;
- we stop at the end of the column}
- PosCh := MinInx;
- while (ColLen > 0) do begin
- if (ColLen > sizeof(Buf)) then
- BytesRead := aInStream.Read(Buf, sizeof(Buf))
- else
- BytesRead := aInStream.Read(Buf, ColLen);
- dec(ColLen, BytesRead);
- for i := 0 to pred(BytesRead) do begin
- MemStream.Position := PosCh;
- inc(PosCh, KeyLen);
- MemStream.Write(Buf[i], 1);
- end;
- end;
- end;
- {now read the temporary stream as letter pairs, converting them
- into the original characters for the output stream}
- MemStream.Position := 0;
- BytesRead := MemStream.Read(DblBuf, sizeof(DblBuf));
- j := 0;
- Row := 0;
- Col := 0;
- while (BytesRead > 0) do begin
- for i := 0 to pred(BytesRead) do begin
- if not Odd(i) then begin
- case DblBuf[i] of
- 'A' : Row := 0;
- 'D' : Row := 1;
- 'F' : Row := 2;
- 'G' : Row := 3;
- 'V' : Row := 4;
- 'X' : Row := 5;
- end;
- case DblBuf[i+1] of
- 'A' : Col := 0;
- 'D' : Col := 1;
- 'F' : Col := 2;
- 'G' : Col := 3;
- 'V' : Col := 4;
- 'X' : Col := 5;
- end;
- Buf[j] := aSubstTable[Row * 6 + Col + 1];
- inc(j);
- if (j = sizeof(Buf)) then begin
- aOutStream.Write(Buf, sizeof(Buf));
- j := 0;
- end;
- end;
- end;
- if (j > 0) then
- aOutStream.Write(Buf, j);
- BytesRead := MemStream.Read(DblBuf, sizeof(DblBuf));
- end;
- finally
- MemStream.Free;
- end;
- end;
- end;
- {--------}
- function AAGenADFGVXTable : TaaADFGVXTable;
- var
- i, j : integer;
- Ch : char;
- begin
- {set the result value to the letters plus digits}
- Result := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
- {now shuffle the characters in the result}
- for i := length(Result) downto 2 do begin
- j := Random(i) + 1;
- if (i <> j) then begin
- Ch := Result[i];
- Result[i] := Result[j];
- Result[j] := Ch;
- end;
- end;
- end;
- {====================================================================}
-
- {====================================================================}
- procedure AAXORCipher(aKey : PByteArray;
- aKeyLen : integer;
- aInStream : TStream;
- aOutStream : TStream);
- var
- Buf : array [0..1023] of byte;
- KeyInx : integer;
- i : integer;
- BytesRead : longint;
- begin
- {read through the input stream in blocks, XOR the block with the key
- and write it to the output stream}
- if (aKey = nil) or (aKeyLen = 0) then
- raise Exception.Create('Cannot encrypt with XOR: the key is missing');
- KeyInx := 0;
- BytesRead := aInStream.Read(Buf, sizeof(Buf));
- while (BytesRead > 0) do begin
- for i := 0 to pred(BytesRead) do begin
- Buf[i] := Buf[i] xor aKey^[KeyInx];
- KeyInx := (KeyInx + 1) mod aKeyLen;
- end;
- aOutStream.Write(Buf, BytesRead);
- BytesRead := aInStream.Read(Buf, sizeof(Buf));
- end;
- end;
- {====================================================================}
-
- end.
-